using GZ.Common.Data;
using Newtonsoft.Json;
using GZ.DB.Repository.wcs_hy;
using GZ.DB.Entity.wcs_hy;
using GZ.DB.IRepository.wcs_hy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Configuration;
using GZ.Projects.WCS_SVC;
using System.Net.NetworkInformation;
using GZ.Common.Code;

namespace GZ.Projects.WCS_SVC
{

	#region IC01.作业任务创建M

	/// <summary>
	/// wms任务下发接口参数
	/// </summary>
	[Serializable]
        
	public class ToWmsCreateOrderRequest
	{
		public string taskNo;
		public string groupNo;
		public string taskType;
		public int priority;
		public string from;
		public string to;
		public string cntrNo;
		public string roadWay; //新增特殊流程使用，巷道号
		public string cntrType;
		public object extData;
	}

	#endregion

	#region IC02.作业任务取消C
	/// <summary>
	/// wms取消任务接口参数
	/// </summary>
	[Serializable]
	public class ToWmsCancelOrderRequest
	{
		public string taskNo;
	}
	#endregion

	#region IC03.设备状态获取G
	[Serializable]
	public class ToWmsGetStateRequest
	{
		public List<string> deviceNo; //设备号列表
	}

	#endregion


	#region IC04.任务优先级调整

	[Serializable]
	public class ToWmsOrderPriorityRequest
	{
		public string taskNo;
		public int priority;
	}

	#endregion

	#region Response
	/// <summary>
	/// 任务下发、取消任务、获取设备状态、修改优先级返回参数
	/// </summary>
	[Serializable]
	public class DeviceData
	{
		public string deviceNo;
		public int workStatus;   //工装状态
		public int photoStatus;  //光电状态
		public int manualStatus; //人工设置状态
	}
	[Serializable]
	public class Data
	{
		public object[] msg;
	}
	[Serializable]
	public class ToWmsResponseOrderData
	{
		public int code;
		public string msg;
		public List<Data> data;
	}
	[Serializable]
	public class ToWmsResponseStateData
	{
		public int code;
		public string msg;
		public List<DeviceData> data;
	}
	#endregion

	#region wms货位转换
	/// <summary>
	/// 转换为wcs货位,并获取排列层
	/// </summary>
	[Serializable]
	public class WcsLoc
	{
		public string transWcs;
		public int pai;
		public int lie;
		public int ceng;
	}

	#endregion
	[Serializable]
	public class ToWmsReportRequest
	{
		public string taskNo;
		public string subTaskNo;  //wcs的子任务号
		public int status;
		public string deviceNo;  //巷道号
		public string errCode;
		public string loc;
	}

	[Serializable]
	public class ToWmsDestRequest
	{
		public string taskNo;
		public string loc;
		public string applyType;
	}

	[Serializable]
	public class ToWmsCntrRequest
	{
		public string cntrNo;
	}

	[Serializable]
	public class ToWmsCntrRequestReponse
	{
		public string deviceNo;
		public string errCode;
		public string errMsg;
	}

	public class WCSTOWMS
	{
		private static readonly string UrlNotify = ConfigurationManager.AppSettings["WcsNotifyTask"];
		private static readonly string UrlDest = ConfigurationManager.AppSettings["WcsApplyDest"];
		/// <summary>
		/// 任务状态上报
		/// </summary>
		public bool FeedInfoToWms(ToWmsReportRequest mainMissionRequest, out string responseMsg ,out int statusCode)
		{
			string msg = $"\r\n[wcs反馈任务信息至wms：Start{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff}";
			statusCode = 0;
			responseMsg = null;
			try
			{
				string input = Json.ToJson(mainMissionRequest);
				msg += $"\r\n\t上报WMS状态json:[{input}]{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff}";
				string json = new HttpClient().Call("POST", input, UrlNotify, out string resMsg,out int resCode);
				msg += $"\r\n\t收到WMS回复json:[{json}]{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff}";
				ToWmsResponseOrderData response = Json.ToObject<ToWmsResponseOrderData>(json);
				if (response != null && response.code == 0) 
				{
					responseMsg = json;
					statusCode = resCode;
					return true;
				}
				else
				{
					responseMsg = json;
					statusCode = resCode;
					return false;
				}
			}
			catch (Exception ex)
			{
				msg += ex.Message;
				responseMsg = ex.Message;
				return false;
			}
			finally
			{
				msg = msg.Replace('\'', '\"');
				Conn.YBLog.Info(1, $"wcs反馈任务信息至wms ", 1, msg);
			}
		}
		public bool ApplyDestToWms(ToWmsDestRequest destRequest, out string responseMsg,out int statusCode)
		{
			string msg = $"\r\n[wcs反馈任务信息至wms：Start{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff}";
			statusCode = 0;
			responseMsg = null;
			try
			{
				string input = Json.ToJson(destRequest);
				msg += $"\r\n\t上报WMS状态json:[{input}]{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff}";
				string json = new HttpClient().Call("POST", input, UrlDest, out string resMsg ,out int resCode);
				msg += $"\r\n\t收到WMS回复json:[{json}]{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff}";
				ToWmsResponseOrderData response = Json.ToObject<ToWmsResponseOrderData>(json);
				if (response != null && response.code == 0)
				{
					responseMsg = json;
					statusCode = resCode;
					return true;
				}
				else
				{
					responseMsg = json;
					statusCode = resCode;
					return false;
				}
			}
			catch (Exception ex)
			{
				msg += ex.Message;
				responseMsg = ex.Message;
				return false;
			}
			finally
			{
				msg = msg.Replace('\'', '\"');
				Conn.YBLog.Info(1, $"wcs反馈任务信息至wms ", 1, msg);
			}
		}
	}
	
	public static class ToWmsHandle
	{
		public static int DeviceTaskIdGen()
		{
			int maxID = 0;
			var taskList = new StackerTaskRepository().FindDataTable("select ID from pcm_MainMission order by ID desc ", new System.Data.Common.DbParameter[0]);
			//让设备编号在200000 -299999内循环 
			if (taskList != null && taskList.Rows.Count > 0)
				maxID = (int)taskList.Rows[0][0] % 100000;

			string id = maxID.ToString().PadLeft(5, '0');
			string prex = string.Empty;
			prex = "2";
			return Convert.ToInt32(prex + id);
		}
		/// <summary>
		/// 任务回复 ToWmsResponseOrderData JSON 文本
		/// </summary>
		private static string BuildResponse(int code, string msg, List<Data> data)
		{
			// 截断 msg 到 256 字符,系统异常返回值太长，需要截断
			if (!string.IsNullOrEmpty(msg) && msg.Length > 256)
				msg = msg.Substring(0, 256);
			if (data == null)
			{
				data = new List<Data>();
			}

			var resp = new ToWmsResponseOrderData //任务回复创建、取消
			{
				code = code,
				msg = msg,
				data = data
			};
			return JsonConvert.SerializeObject(resp);
		}

		private static string DvcStateResponse(int code, string msg, List<DeviceData> data)
		{
			// 截断 msg 到 256 字符,系统异常返回值太长，需要截断
			if (!string.IsNullOrEmpty(msg) && msg.Length > 256)
				msg = msg.Substring(0, 256);
			if (data == null)
				data = new List<DeviceData>();
			
			var resp = new ToWmsResponseStateData //状态获取回复
			{
				code = code,
				msg = msg,
				data = data
			};
			return JsonConvert.SerializeObject(resp);
		}

		/// <summary>
		/// IC01.作业任务创建M
		/// </summary>
		/// <param name="requestJson"></param>
		/// <returns></returns>
		public static string CreateOrder(string requestJson)
		{
			//string respJson = string.Empty;
			try
			{
				var requestList = JsonConvert.DeserializeObject<List<ToWmsCreateOrderRequest>>(requestJson);
				if (requestList == null)
				{
					return BuildResponse(-1, "收到的json格式不正确", null);
				}
				List<MainMissionEntity> mainMissionList = new List<MainMissionEntity>();
				foreach (var request in requestList)
				{
					// 1. 任务号不能为空
					if (string.IsNullOrEmpty(request.taskNo))
					{
						return BuildResponse(-1, "taskNo不能为空", null);
					}
					// 2. 托盘号不能为空
					if (string.IsNullOrEmpty(request.cntrNo))
					{
						return BuildResponse(-1, "cntrNo不能为空", null);
					}
					// 3. 起始库位不能为空
					if (string.IsNullOrEmpty(request.from))
					{
						return BuildResponse(-1, "from不能为空", null);
					}
					// 4. 入库的巷道号不能为空
					if (string.IsNullOrEmpty(request.roadWay) && request.taskType == "入库")
					{
						return BuildResponse(-1, "入库roadWay不能为空", null);
					}
					// 5. 组号不能为空
					if (string.IsNullOrEmpty(request.groupNo))
					{
						return BuildResponse(-1, "groupNo不能为空", null);
					}

					MainMissionEntity mission = new MainMissionEntity();
					mission.order_no = request.taskNo;
					mission.task_no = request.taskNo;
					int deviceTaskId = DeviceTaskIdGen(); // 在循环外获取初始ID值
					mission.device_task_no = (deviceTaskId + requestList.IndexOf(request)).ToString(); // 为每个任务递增ID
					mission.tray_code = request.cntrNo;
					mission.group_no = request.groupNo;
					mission.order_priority = request.priority;
					mission.task_priority = request.priority;
					// 使用StationConvertHelper转换from/to为WCS货位
					// 如果是LXK-、TPK-格式则不转换，其他通过字典转换
					string convertedFrom = StationConvertHelper.ConvertWmsToWcs(request.from);
					string convertedTo = StationConvertHelper.ConvertWmsToWcs(request.to);
					mission.start_position = convertedFrom; 
					mission.start_position = string.IsNullOrEmpty(convertedTo) ? "NULL" : convertedTo;

					switch (request.taskType)
					{
						case "入库":
							mission.task_type = "ST_In";
							mission.order_type = "R";
							break;
						case "出库":
							mission.task_type = "ST_Out";
							mission.order_type = "C";
							break;
						case "移库":
							mission.task_type = "ST_Move";
							mission.order_type = "Y";
							break;
						case "盘点":
							mission.task_type = "ST_Check";
							mission.order_type = "P";
							break;
						default:
							mission.task_type = "null";
							mission.order_type = "null";
							break;
					}
					mission.tunnel_no = request.roadWay; //入库巷道号
					mission.tray_type = request.cntrType;
					mission.MissionState = "Create";
					mission.CreateTime = DateTime.Now;
					mission.ope_time = DateTime.Now;
					mission.InteStationNo = convertedFrom;
					mission.SyncFlag = "U"; //未同步
					//判断任务号是否已存在
					IMainMissionRepository mainMissionRepository = new MainMissionRepository();
					MainMissionEntity mainMission = mainMissionRepository.FindEntity(m => m.task_no == request.taskNo);
					if (mainMission != null)
					{
						//任务号已存在
						return BuildResponse(-1, "任务号已存在，请检查任务号是否正确！", null);
					}
					mainMissionList.Add(mission);
				}
				if (mainMissionList.Count > 0)
				{
					//写入数据库
					AutoScanApp autoScanApp = new AutoScanApp();
					bool mainResult = autoScanApp.AddMainMissionList(mainMissionList, out string mainMsg);
					if (!mainResult)
					{
						//任务写入数据库失败
						return BuildResponse(-1, "数据库任务写入失败" + mainMsg, null);
					}
				}
				
				return BuildResponse(0, "success", null);
			}
			catch (Exception ex)
			{
				return BuildResponse(-1, "捕获异常"+ex.Message, null);
			}
		}

		/// <summary>
		/// IC02.作业任务取消
		/// </summary>
		/// <param name="requestJson"></param>
		/// <returns></returns>
		public static string CancelTask(string requestJson)
		{
			//todo 取消任务没判断入出库任务是否已经发给堆垛机了没，是否已经发给agv了
			//string respJson = string.Empty;
			try
			{
				var request = JsonConvert.DeserializeObject<ToWmsCancelOrderRequest>(requestJson);
				if (request == null)
				{
					return BuildResponse(-1, "收到的json格式不正确", null);
				}
				else
				{
					// 1. 任务号不能为空
					if (string.IsNullOrEmpty(request.taskNo))
					{
						return BuildResponse(-1, "taskNo不能为空", null);
					}

					//任务执行中不能取消
					IMainMissionRepository mainMissionRepository = new MainMissionRepository();
					//任务号已存在
					MainMissionEntity mainMission = mainMissionRepository.FindEntity(m => m.task_no == request.taskNo);
					if (mainMission == null)
					{
						//任务号不存在
						return BuildResponse(-1, "任务号不存在，请检查任务号是否正确！", null);
					}
					else if (mainMission.MissionState == "Doing")
					{
						//任务已创建
						return BuildResponse(-1, "任务正在执行中，不能取消", null);
					}
					else if (mainMission.MissionState == "Cancel" || mainMission.MissionState == "Error")
					{
						//任务已创建
						return BuildResponse(-1, "任务已取消，不能取消", null);
					}
					else
					{
						//通过任务号查询任务修改状态为取消状态
						mainMission.MissionState = "Cancel";
						mainMission.ope_time = DateTime.Now;
						mainMission.LastUpdatedTime = DateTime.Now;
						mainMission.MissionEndTime = DateTime.Now;
						//判断任务写入数据库是否成功
						AutoScanApp autoScan = new AutoScanApp();
						bool mainResult = autoScan.UpdateMainMissionTask(mainMission, out string mainMsg);
						if (!mainResult)
						{
							//任务状态修改失败
							return BuildResponse(-1, "任务写入失败" + mainMsg, null);
						}

						//任务状态修改成功
						return BuildResponse(0, "success", null);
					}
				}
			}
			catch (Exception ex)
			{
				return BuildResponse(-1, ex.Message, null);
			}
		}

		/// <summary>
		/// IC03.设备状态获取
		/// </summary>
		/// <param name="requestJson"></param>
		/// <returns></returns>
		public static string GetDvcState(string requestJson)
		{
			//string respJson = string.Empty;
			try
			{
				var request = JsonConvert.DeserializeObject<ToWmsGetStateRequest>(requestJson);
				if (request == null)
				{
					return DvcStateResponse(-1, "收到的json格式不正确", null);
				}
				else
				{
					// 1. 设备号不能为空
					if (request.deviceNo == null || request.deviceNo.Count == 0)
					{
						return DvcStateResponse(-1, "请求deviceNo的数组不能为空", null);
					}

					List<DeviceData> deviceDataList = new List<DeviceData>();
					foreach (var deviceNo in request.deviceNo)
					{
						if (string.IsNullOrEmpty(deviceNo))
						{
							continue;
						}

						//根据设备号查询设备状态
						DeviceData deviceData = new DeviceData();
						deviceData.deviceNo = deviceNo;
						deviceData.workStatus = 1;
						deviceData.photoStatus = 1;
						deviceData.manualStatus = 1;
						deviceDataList.Add(deviceData);
					}

					return DvcStateResponse(0, "success", deviceDataList);
				}
			}
			catch (Exception ex)
			{
				return DvcStateResponse(-1, ex.Message, null);
			}
		}

		/// <summary>
		/// IC04.任务优先级调整
		/// </summary>
		/// <param name="requestJson"></param>
		/// <returns></returns>
		public static string ModifyPriority(string requestJson)
		{
			//string respJson = string.Empty;
			try
			{
				var request = JsonConvert.DeserializeObject<ToWmsOrderPriorityRequest>(requestJson);
				if (request == null)
				{
					return BuildResponse(-1, "收到的json格式不正确", null);
				}
				else
				{
					// 1. 任务号不能为空
					if (string.IsNullOrEmpty(request.taskNo))
					{
						return BuildResponse(-1, "taskNo不能为空", null);
					}
					// 2. 优先级不能为空
					if (request.priority <= 0)
					{
						return BuildResponse(-1, "priority不能为负数", null);
					}
					//1.查主任务是否为出库并且确认堆垛机任务是否已经执行了
					//2.可能存在出库任务还没分解，需要确定主任务的状态
					//3.准备将任务号、优先级等信息存入数据库
					IMainMissionRepository mainMissionRepository = new MainMissionRepository();
					//任务号已存在
					MainMissionEntity mission = mainMissionRepository.FindEntity(m => m.task_no == request.taskNo && m.task_type == "ST_Out"  && (m.MissionState != "Cancel" && m.MissionState != "Error"));
					if (mission != null)
					{
						IStackerTaskRepository stackerTaskRepository = new StackerTaskRepository();
						StackerTaskEntity stackerTask = stackerTaskRepository.FindEntity(m => m.TaskNo == mission.task_no && (m.TaskState == "Create" || m.TaskState== "Pre" ));
						if (stackerTask != null)
						{
							mission.task_priority = request.priority;
							mission.LastUpdatedTime = DateTime.Now;
							stackerTask.PriorityLevel = request.priority;
							stackerTask.LastUpdatedTime = DateTime.Now;
							//判断任务写入数据库是否成功
							AutoScanApp autosan = new AutoScanApp();
							bool mainbl = autosan.UpdateStackerAndMainTask(stackerTask,mission, out string mainessmage);
							if (mainbl)
							{
								return BuildResponse(0, "success", null);
							}
							else
							{
								return BuildResponse(-1, "堆垛机或主任务写入失败" + mainessmage, null);
							}
						}
						else
						{
							mission.task_priority = request.priority;
							mission.ope_time = DateTime.Now;
							//判断任务写入数据库是否成功
							AutoScanApp autosan = new AutoScanApp();
							bool mainbl = autosan.UpdateMainMissionTask(mission, out string mainessmage);
							if (mainbl)
							{
								return BuildResponse(0, "success", null);
							}
							else
							{
								return BuildResponse(-1, "主任务写入失败" + mainessmage, null);
							}
						}
						
					}
					else
					{
						return BuildResponse(-1, "请检查任务号[" + request.taskNo + "]的状态是否正确！", null);
					}
				}
			}
			catch (Exception ex)
			{
				return BuildResponse(-1, ex.Message, null);
			}
		}
	}

}